"""
Created on Tue Jul 23 12:54:50 2013

@author: chico
"""


import sys
from PySide import QtCore, QtGui, QtWebKit
from libatomism import *
import inspect
import re
from simpletreemodel import *
import functools
import unicodedata
import Widgets
from uiNewClassScriptTemplate import *
from uiNewGraphicScriptTemplate import *

def getArgsType(docstr):
    
    definition = docstr.split(':')[0]
    arguments=[]
    arguments.append(definition)
    if(',' in definition):
        arguments=definition.split(',')
    result=[]
    for argument in arguments:
        arg = re.search(r"\((\w+)\)",argument)
        try:
            result.append(arg.group(1))
        except:
            a=0
    print "agrs:",result    
    return result
        

class uiMethodWidget(QtGui.QWidget):
    
    def __init__(self,method,parent,mainwindow):
        super(uiMethodWidget, self).__init__()
        self.method = method  
        self.parent = parent
        self.isTreeViewReturnDisplayed=0
        self.isreturn = 0
        self.arguments = []
        self.mainwindow = mainwindow
        self.initUI()
        
    def initUI(self):
        
        vbox = QtGui.QVBoxLayout()
        
        vbox.addWidget(QtGui.QLabel("Documentation: " + inspect.getdoc(self.method) ))
        
        """ Create the arguments groupbox
        """        
        arglist =getArgsType(inspect.getdoc(self.method))
        
        start=0
        if(str(type(self.method))=="<type 'instancemethod'>"):
            start=1
        
        if len(arglist)>start:
            self.groupboxArgs = QtGui.QGroupBox("Arguments")
            vboxargs = QtGui.QVBoxLayout()
            
            i = 0
            for arg in arglist[start:]:
                vboxargs.addWidget(QtGui.QLabel("Argument of type: " + arg))
                if 'str' in arg:
                    textarg = QtGui.QTextEdit()
                    vboxargs.addWidget(textarg)
                    fct=functools.partial(self.addArgumentFromString, textarg.toPlainText ,i)
                    textarg.textChanged.connect(fct)
                    
                elif 'int' in arg:
                    intarg = QtGui.QSpinBox()
                    vboxargs.addWidget(intarg)
                    fct=functools.partial(self.addArgumentFromInt, intarg.value , i )
                    intarg.valueChanged.connect(fct)
                else:
                    treeview = QtGui.QTreeView()
                    vboxargs.addWidget(treeview)
                    model = TreeModel(self.parent,arg)
                    treeview.setModel(model)
                    fct=functools.partial(self.addArgumentFromTreeview,treeview,i)
                    treeview.clicked.connect(fct)
                    
                i = i+1
                self.arguments.append(None)
                
            self.groupboxArgs.setLayout(vboxargs)
            vbox.addWidget(self.groupboxArgs)
        
        """ Create the return GroupBox
        """
        if( not '-> None' in inspect.getdoc(self.method)):
            
            self.groupboxReturn = QtGui.QGroupBox("Return")
            
            self.vboxreturn = QtGui.QVBoxLayout()
                        
            if( '-> str' in inspect.getdoc(self.method)):
                self.vboxreturn.addWidget(QtGui.QLabel("result returned in out stream"))
            else:
                hbox=QtGui.QHBoxLayout()
                hbox.addWidget(QtGui.QLabel("msTreeMapper return type, options"))
                
                vboxopt=QtGui.QVBoxLayout()
                button=QtGui.QRadioButton("Ignore")
                button.setChecked(1)                
                button.clicked.connect(self.hideTreeToAddChild)
                
                vboxopt.addWidget(button)
                button=QtGui.QRadioButton("Add as new child")
                button.clicked.connect(self.displayTreeToAddChild)
                
                vboxopt.addWidget(button)
                hbox.addLayout(vboxopt)
                
                self.vboxreturn.addLayout(hbox)
                
            self.groupboxReturn.setLayout(self.vboxreturn)
            vbox.addWidget(self.groupboxReturn)
            
        button = QtGui.QPushButton("execute")
        button.setMaximumWidth(200)
        button.clicked.connect(self.execute)
        vbox.addWidget(button)
        self.setLayout(vbox)
         
    def addArgument(self, getdata, i ):
        self.arguments[i]=getdata()
   
    def addArgumentFromString(self, getdata, i , a ):
        self.arguments[i]=str(getdata())

    def addArgumentFromInt(self, getdata, i , a):
        self.arguments[i]=int(getdata())
        print self.arguments[i]

    def addArgumentFromTreeview(self, treeview , i , a):
        self.arguments[i]=treeview.currentIndex().internalPointer().getRawdata()
             
    def displayTreeToAddChild(self):
        if( not self.isTreeViewReturnDisplayed):
            self.treeviewReturn = QtGui.QTreeView()
            model = TreeModel(self.parent,"msTreeMapper")
            self.treeviewReturn.setModel(model)
            self.vboxreturn.addWidget(self.treeviewReturn)
            self.isTreeViewReturnDisplayed=1
            self.NameVariable = QtGui.QLineEdit()
            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(QtGui.QLabel("Nom de la variable"))
            hbox.addWidget(QtGui.QPushButton("check reserved variable name"))
            self.vboxreturn.addLayout(hbox)
            self.vboxreturn.addWidget(self.NameVariable)
        self.treeviewReturn.setVisible(1)
        self.isreturn = 1
         
    def hideTreeToAddChild(self):
        self.isreturn = 0
        if( self.isTreeViewReturnDisplayed):
            self.treeviewReturn.setVisible(0)
            
    def execute(self):
        try:
            if(len(self.arguments)==0):
                a = self.method()
            if(len(self.arguments)>0):
                a = self.method(*self.arguments)
            if(self.isreturn):
                if(str(self.NameVariable.text())==""):
                    ret=QtGui.QMessageBox.critical(self,'An exception occured',
                                           'You need to set the variable name', 
                                           QtGui.QMessageBox.Yes,
                                           QtGui.QMessageBox.Yes)
                    return
                try:
                    self.treeviewReturn.currentIndex().internalPointer().getRawdata().addChild(a,str(self.NameVariable.text()))
                except:
                    ret=QtGui.QMessageBox.critical(self,'An exception occured',
                                           'You need to select the parent to store the returned object', 
                                           QtGui.QMessageBox.Yes,
                                           QtGui.QMessageBox.Yes) 
            model = TreeModel(self.mainwindow.rootObject,"msTreeMapper")
            self.mainwindow.mainTreeWidget.setModel(model)
        
        except:
            message = str(sys.exc_info())
            self.mainwindow.reportException(sys.exc_info())
            """        
            ret=QtGui.QMessageBox.critical(self,'An exception occured',
                                           'Exception:'+message, 
                                           QtGui.QMessageBox.Yes,
                                           QtGui.QMessageBox.Yes) 
            """
        
        self.close()
        
    def treeviewclick(self):
        print self.treeview.currentIndex()
        print self.treeview.currentIndex().internalPointer().getRawdata().getId()
        
        
                    
class uiNewScriptTemplatePopUp(QtGui.QWidget):
    
    def __init__(self,scriptwidget):
        super(uiNewScriptTemplatePopUp, self).__init__()
        
        self.scriptWidget = scriptwidget
        self.listChoice=[]
        self.listChoice.append( ("Database object", "A new objet definition that can be manage by the database" , uiNewClassScriptTemplate  ) )        
        self.listChoice.append( ("Graphical component", "A new graphical component for a database object" , uiNewGraphicScriptTemplate ) )
        self.initUI()
        
    def initUI(self):
        
        self.hbox = QtGui.QHBoxLayout()
        vbox = QtGui.QVBoxLayout()
        
        self.listView = QtGui.QListWidget()
        self.listView.clicked.connect(self.listClick)
        for item in self.listChoice:
            self.listView.addItem(item[0])
        vbox.addWidget(self.listView)
        
        self.hbox.addLayout(vbox)
        
        self.vbox = QtGui.QVBoxLayout()        
        labelHelp = QtGui.QLabel("Click on items for help")
        self.vbox.addWidget(labelHelp)
        self.hbox.addLayout(self.vbox)
        
        self.setLayout(self.hbox)

    def listClick(self):
        i = self.listView.row( self.listView.currentItem()) 
        b = self.vbox.takeAt(0)
        while b:
            b.widget().deleteLater()
            b = self.vbox.takeAt(0)
          
        labelHelp = QtGui.QLabel(self.listChoice[i][1] )
        self.vbox.addWidget(labelHelp)
        widget = self.listChoice[i][2](self.scriptWidget, self )
        self.vbox.addWidget( widget )
        

class uiException(QtGui.QWidget):
    
    def __init__(self, message, sys):
        super(uiException, self).__init__()
        
        self.description = str(sys.exc_info())
        self.initUI()
        
    def initUI(self):
        
        vbox = QtGui.QVBoxLayout()
        listStr = self.description.split('\n')
        
        for elem in listStr:
            vbox.addWidget(QtGui.QLabel(elem))
        
        button = QtGui.QPushButton("ok")
        button.setMaximumWidth(200)
        vbox.addWidget(button)
        self.setLayout(vbox)
